#include "timer.h"
#include "asyncservice.h"
#include "timerservice.h"
#include <boost/bind.hpp>

TimerService::TimerService(AsyncService &service) :
    m_service(service),
    m_timerFactory(service)
{

}

TimerService::~TimerService()
{

}

int TimerService::setTimer(unsigned int owner,
                           unsigned int id,
                           unsigned long elapse,
                           unsigned int repeat,
                           BOOST_ASIO_MOVE_ARG(Notifier) n)
{
    TimerMapPtr tmp;

    Mutex::scoped_lock timerLock(m_timerLock);

    OwnerMap::iterator it_ow = m_timers.find(owner);

    if(it_ow == m_timers.end()){
        tmp = TimerMapPtr(new TimerMap());

        if(!tmp){
            return boost::system::errc::not_enough_memory;
        }

        m_timers.insert(OwnerMap::value_type(owner, tmp));

        TimerPtr timer = m_timerFactory.create(owner, id, elapse, repeat);

        if(!timer){
            return boost::system::errc::not_enough_memory;
        }

        timer->start(boost::bind(&TimerService::onTimeout, this, Notifier(n), timer, _1));

        tmp->insert(TimerMap::value_type(id, timer));
    }else{
        tmp = it_ow->second;

        TimerMap::iterator it = tmp->find(id);

        if(it != tmp->end()){
            return boost::system::errc::operation_in_progress;
        }

        TimerPtr timer = m_timerFactory.create(owner, id, elapse, repeat);

        if(!timer){
            return boost::system::errc::not_enough_memory;
        }

        timer->start(boost::bind(&TimerService::onTimeout, this, Notifier(n), timer, _1));

        tmp->insert(TimerMap::value_type(id, timer));
    }

    return 0;
}

void TimerService::killTimer(unsigned int owner, unsigned int id)
{
    if(!id){

    }else{

    }
}

void TimerService::onTimeout(Notifier n, TimerPtr timer, int err)
{
    if(err){
        killTimer(timer->owner(), timer->id());
        return;
    }

    n(timer->owner(), timer->id());
}
